package com.zkt.subject.domain.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjUtil;
import com.zkt.subject.common.constants.SubjectConstant;
import com.zkt.subject.domain.convert.SubjectCategoryConverter;
import com.zkt.subject.domain.convert.SubjectLabelConverter;
import com.zkt.subject.domain.entity.SubjectCategoryBO;
import com.zkt.subject.domain.entity.SubjectLabelBO;
import com.zkt.subject.domain.entity.SubjectUserLabelBO;
import com.zkt.subject.domain.service.SubjectUserLabelDomainService;
import com.zkt.subject.infra.basic.entity.SubjectCategory;
import com.zkt.subject.infra.basic.entity.SubjectLabel;
import com.zkt.subject.infra.basic.entity.SubjectUserLabel;
import com.zkt.subject.infra.basic.service.ISubjectCategoryService;
import com.zkt.subject.infra.basic.service.ISubjectLabelService;
import com.zkt.subject.infra.basic.service.ISubjectUserLabelService;
import com.zkt.subject.infra.entity.UserInfo;
import com.zkt.subject.infra.rpc.RecommendRPC;
import jakarta.annotation.Resource;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.stereotype.Service;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 赵开泰
 * @program jc-club
 * @date 2025/3/27
 * @description 用户标签关系service层实现类
 **/

@Service
public class SubjectUserLabelDomainServiceImpl implements SubjectUserLabelDomainService {
	
	@Resource
	private ISubjectCategoryService subjectCategoryService;
	
	@Resource
	private ISubjectLabelService subjectLabelService;
	
	@Resource
	private ISubjectUserLabelService subjectUserLabelService;
	
	@Resource
	private RocketMQTemplate rocketMQTemplate;
	
	@Resource
	private RecommendRPC recommendRPC;
	
	/**
	 * 添加用户标签关系
	 *
	 * @param subjectUserLabelBO 用户标签关系
	 * @return 是否成功
	 */
	@Override
	public Boolean add(SubjectUserLabelBO subjectUserLabelBO) {
		List<SubjectUserLabel> subjectUserLabelList = new LinkedList<>();
		
		subjectUserLabelBO.getLabelIds().forEach(labelId -> {
			SubjectUserLabel subjectUserLabel = new SubjectUserLabel();
			subjectUserLabel.setLabelId(labelId);
			subjectUserLabel.setUserId(subjectUserLabelBO.getUserId());
			subjectUserLabelList.add(subjectUserLabel);
			
			rocketMQTemplate.convertAndSend(SubjectConstant.DEAL_NEW_USER_LABEL, subjectUserLabel);
		});
		
		return subjectUserLabelService.saveBatch(subjectUserLabelList);
	}
	
	/**
	 * 删除用户标签关系
	 *
	 * @param subjectUserLabelBO 需要删除的用户标签关系
	 * @return 是否成功
	 */
	@Override
	public Boolean remove(SubjectUserLabelBO subjectUserLabelBO) {
		List<Long> subjectUserLabelIdList = subjectUserLabelService.lambdaQuery()
				.eq(SubjectUserLabel::getUserId, subjectUserLabelBO.getUserId())
				.in(SubjectUserLabel::getLabelId, subjectUserLabelBO.getLabelIds())
				.list()
				.stream()
				.map(SubjectUserLabel::getId)
				.toList();
		
		recommendRPC.removeUserPortrait(subjectUserLabelBO.getUserId(), subjectUserLabelBO.getLabelIds());
		
		return subjectUserLabelService.removeBatchByIds(subjectUserLabelIdList);
	}
	
	/**
	 * 获取用户期望标签
	 *
	 * @param userInfo 用户信息
	 * @return 用户信息
	 */
	@Override
	public List<SubjectLabelBO> getUserLabels(UserInfo userInfo) {
		if (ObjUtil.isEmpty(userInfo.getId())) {
			return ListUtil.empty();
		}
		
		List<Long> labelIdList = subjectUserLabelService.lambdaQuery()
				.eq(SubjectUserLabel::getUserId, userInfo.getId())
				.list()
				.stream()
				.map(SubjectUserLabel::getLabelId)
				.toList();
		
		if (CollUtil.isEmpty(labelIdList)) {
			return ListUtil.empty();
		}
		
		List<SubjectLabel> subjectLabelList = subjectLabelService.listByIds(labelIdList);
		
		return SubjectLabelConverter.INSTANCE.convertLabelToBoList(subjectLabelList);
	}
	
	/**
	 * 获取用户期望的分类和标签
	 *
	 * @param userInfo 用户信息
	 * @return 用户信息
	 */
	@Override
	public List<SubjectCategoryBO> queryCategoryAndLabel(UserInfo userInfo) {
		List<SubjectLabelBO> subjectLabelBOList = this.getUserLabels(userInfo);
		
		if (CollUtil.isEmpty(subjectLabelBOList)) {
			return ListUtil.empty();
		}
		
		List<Long> categoryList = subjectLabelBOList.stream().map(SubjectLabelBO::getCategoryId).toList();
		
		List<SubjectCategory> subjectCategorieList = subjectCategoryService.listByIds(categoryList);
		List<SubjectCategoryBO> subjectCategoryBOList = SubjectCategoryConverter.INSTANCE.convertCategoryToBo(subjectCategorieList);
		List<Long> parentIdList = subjectCategoryBOList.stream().map(SubjectCategoryBO::getParentId).toList();
		subjectCategoryBOList.forEach(t -> t.setLabelBOList(new LinkedList<>()));
		Map<Long, SubjectCategoryBO> subjectCategoryBOMap = subjectCategoryBOList.stream()
				.collect(Collectors.toMap(SubjectCategoryBO::getId, category -> category));
		
		subjectLabelBOList.forEach(subjectLabelBO -> {
			if (subjectCategoryBOMap.containsKey(subjectLabelBO.getCategoryId())) {
				subjectCategoryBOMap.get(subjectLabelBO.getCategoryId()).getLabelBOList().add(subjectLabelBO);
			}
		});
		
		List<SubjectCategory> subjectCategories = subjectCategoryService.listByIds(parentIdList);
		List<SubjectCategoryBO> subjectCategoryBOs = SubjectCategoryConverter.INSTANCE.convertCategoryToBo(subjectCategories);
		subjectCategoryBOs.forEach(t -> t.setCategoryBOList(new LinkedList<>()));
		Map<Long, SubjectCategoryBO> subjectCategoryBOResultMap = subjectCategoryBOs.stream()
				.collect(Collectors.toMap(SubjectCategoryBO::getId, category -> category));
		
		subjectCategoryBOMap.values().forEach(subjectCategoryBO -> {
			if (subjectCategoryBOResultMap.containsKey(subjectCategoryBO.getParentId())) {
				subjectCategoryBOResultMap.get(subjectCategoryBO.getParentId()).getCategoryBOList().add(subjectCategoryBO);
			}
		});
		
		return subjectCategoryBOResultMap.values().stream().toList();
	}
	
}